
local threatfont = "Interface\\Addons\\TidyPlates\\Media\\LiberationSans-Regular.ttf"

---------------
-- General Functions
---------------

local function SetFade(frame)
	if GetTime() > frame.FadeTime then
		frame:Hide()
		frame:SetScript("OnUpdate", nil)
	end
end

---------------
-- Threat Functions
---------------
local function GetThreatSegment(threat)
	if not threat then return nil end
	if threat > 135 then return "HIGHTANK"
	elseif threat > 110 then return "MEDIUMTANK"
	elseif threat > 100 then return "LOWTANK"
	elseif threat > 85 then return "HIGHDPS"
	elseif threat > 55 then return "MEDIUMDPS"
	else return "LOWDPS"  end
end

local function GetRelativeThreat(unit)
	if not UnitExists(unit) then return end
	local _, group, size, index, unitid
	local playerthreat, leaderthreat, tempthreat, petthreat, leadername  = 0,0,0,0, nil
	-- Request Player Threat
	_, _,  playerthreat, _, _ = UnitDetailedThreatSituation("player", unit)
	-- Request Pet Threat
	if HasPetUI() then 
		_, _,  petthreat, _, _ = UnitDetailedThreatSituation("pet", unit)
		leaderthreat = petthreat or 0
		leadername = "pet" 
	end
	-- Get Group Type
	if UnitInRaid("player") then group = "raid"; size = GetNumRaidMembers() - 1
	elseif UnitInParty("player") then group = "party"; size = GetNumPartyMembers()
	else group = nil end
	-- Cycle through Group, picking highest threat holder
	if group then
		for index = 1, size do
			unitid = group..index
			_, _, tempthreat , _, _ = UnitDetailedThreatSituation(unitid, unit)
			if tempthreat and tempthreat > leaderthreat then 
				leaderthreat = tempthreat 
				leadername = unitid
				end
		end
	end
	
	if playerthreat and leaderthreat then
		if playerthreat == 100 then return playerthreat + (100-leaderthreat), nil
		else return playerthreat, leadername end
	else return end
end


---------------
-- Threat Circle Widget
---------------
do
	local threatSpinnerWidgetPath = "Interface\\Addons\\TidyPlates\\Widgets\\ThreatSpinner\\"

	local THREATWIDGET_SEGMENT_ART = {
		HIGHTANK = threatSpinnerWidgetPath.."Red",
		MEDIUMTANK = threatSpinnerWidgetPath.."Orange",
		LOWTANK = threatSpinnerWidgetPath.."Yellow",
		HIGHDPS = threatSpinnerWidgetPath.."Green",
		MEDIUMDPS = threatSpinnerWidgetPath.."Blue",
		LOWDPS = threatSpinnerWidgetPath.."Blue",
		UNKNOWN = threatSpinnerWidgetPath.."Unknown",
	}

	local function UpdateThreatWidget(frame, unit)
		local unitid
		if unit.reaction == "FRIENDLY" or (not InCombatLockdown()) then frame:Hide(); return end
		if unit.isTarget and UnitExists("target") then unitid = "target"
		elseif unit.isMouseover then unitid = "mouseover" end
		if unitid then
			local threat, topholder = GetRelativeThreat(unitid) 
			local threatsegment = GetThreatSegment(threat)
			if threatsegment then
				-- Set Indicator
				frame:Show()
				frame.ThreatIcon:SetTexture(THREATWIDGET_SEGMENT_ART[threatsegment])
				frame.ThreatText:SetText(floor(threat))
				if topholder then frame.TargetText:SetText(UnitName(topholder))
				else frame.TargetText:SetText("") end
				-- Set Fading
				frame.FadeTime = GetTime() + 3
				frame:SetScript("OnUpdate", SetFade)
			else frame:Hide() end
		elseif (GetTime() > frame.FadeTime) then frame:Hide() end
	end

	local function CreateSpinnerThreatWidget(parent)
		local frame = CreateFrame("Frame", nil, parent)
		frame:SetWidth(64)
		frame:SetHeight(64)
		-- Icon
		frame.ThreatIcon = frame:CreateTexture(nil, "OVERLAY")
		frame.ThreatIcon:SetAllPoints(frame)
		-- Threat Text
		frame.ThreatText = frame:CreateFontString(nil, "OVERLAY")
		frame.ThreatText:SetFont(threatfont, 8, "NONE")
		frame.ThreatText:SetPoint("CENTER",frame.ThreatIcon,"CENTER", -1, 0)
		frame.ThreatText:SetWidth(20)
		frame.ThreatText:SetHeight(20)
		-- Target Text
		frame.TargetText = frame:CreateFontString(nil, "OVERLAY")
		frame.TargetText:SetFont(threatfont, 8, "NONE")
		frame.TargetText:SetShadowOffset(1, -1)
		frame.TargetText:SetShadowColor(0,0,0,1)
		frame.TargetText:SetPoint("BOTTOM",frame,"TOP", 1, -25)
		frame.TargetText:SetWidth(50)
		frame.TargetText:SetHeight(20)
		-- Setup
		frame.FadeTime = 0
		frame:Hide()
		frame.Update = UpdateThreatWidget
		return frame
	end

	TidyPlatesWidgets.CreateSpinnerThreatWidget = CreateSpinnerThreatWidget
end

---------------
-- Threat Line Widget
---------------
do
	local THREATWIDGET_LOW_COLOR = { r = .14, g = .75, b = 1}
	local THREATWIDGET_HIGH_COLOR = {r = 1, g = .67, b = .14}
	local artpath = "Interface\\Addons\\TidyPlates\\Widgets\\ThreatLine\\"
	local threatcolor
	
	local function UpdateThreatLineWidget(frame, unit)
		local unitid
		if unit.reaction == "FRIENDLY" or (not InCombatLockdown()) then frame:Hide(); return end
		if unit.isTarget and UnitExists("target") then unitid = "target"
		elseif unit.isMouseover then unitid = "mouseover" end
		
		if unitid then
			local threat, topholder = GetRelativeThreat(unitid) 
			local middledot, outerdot = "Left", "Right"
			if threat and threat > 0 then
				local lineAnchor, dotAnchor, lineWidth = "RIGHT", "LEFT", 0
				-- Get Positions and Size
				if threat > 100 then
					-- While tanking
					lineWidth = ceil((threat - 100)/2)
					lineAnchor, dotAnchor = "LEFT", "RIGHT"
					--print("Tanking")
					threatcolor = THREATWIDGET_HIGH_COLOR
					frame.TargetText:SetText("")
				else 
					-- While NOT tanking
					lineWidth = ceil((100 - threat)/2)
					threatcolor = THREATWIDGET_LOW_COLOR
					middledot, outerdot = "Right", "Left"
				end
				if topholder then 
					frame.TargetText:SetText(UnitName(topholder)) 
				else frame.TargetText:SetText("") end
				-- Set Size
				frame.Line:ClearAllPoints()
				frame.Line:SetPoint(lineAnchor, frame.Middle, "CENTER")
				frame.Line:SetWidth(lineWidth)
				frame.Dot:ClearAllPoints()
				frame.Dot:SetPoint("CENTER", frame.Line, dotAnchor)
				-- Set Colors
				frame.Dot:SetVertexColor(threatcolor.r, threatcolor.g, threatcolor.b)
				frame.Line:SetVertexColor(threatcolor.r, threatcolor.g, threatcolor.b)
				frame.Middle:SetVertexColor(threatcolor.r, threatcolor.g, threatcolor.b)
				-- Set Textures
				frame.Middle:SetTexture(artpath..middledot.."Dot")
				frame.Dot:SetTexture(artpath..outerdot.."Dot")
				-- Set Fading
				frame:Show()
				frame.FadeTime = GetTime() + 3
				frame:HideIn(frame.FadeTime)
			else frame:Hide() end
		elseif (GetTime() > frame.FadeTime) then frame:Hide() end
	end

	local function CreateThreatLineWidget(parent, showname, hangtime, art)
		local frame = CreateFrame("Frame", nil, parent)
		frame:SetWidth(100)
		frame:SetHeight(24)
		-- Threat Center
		frame.Middle = frame:CreateTexture(nil, "OVERLAY")
		frame.Middle:SetPoint("CENTER")
		frame.Middle:SetWidth(32)
		frame.Middle:SetHeight(32)
		-- Threat Dot
		frame.Dot = frame:CreateTexture(nil, "OVERLAY")
		frame.Dot:SetWidth(32)
		frame.Dot:SetHeight(32)
		-- Threat Line
		frame.Line = frame:CreateTexture(nil, "OVERLAY")
		frame.Line:SetTexture(artpath.."Threatline")
		frame.Line:SetWidth(32)
		frame.Line:SetHeight(32)
		-- Target Text
		frame.TargetText = frame:CreateFontString(nil, "OVERLAY")
		frame.TargetText:SetFont(threatfont, 9, "NONE")
		frame.TargetText:SetPoint("BOTTOM",frame.Dot,"TOP", 0, -15)
		frame.TargetText:SetWidth(50)
		frame.TargetText:SetHeight(20)
		-- Mechanics/Setup
		frame.HideIn = TidyPlatesWidgets.HideIn
		frame.FadeTime = 0
		frame:Hide()
		frame.UpdateThreat = UpdateThreatLineWidget
		frame.Update = UpdateThreatLineWidget
		return frame
	end
	
	TidyPlatesWidgets.CreateThreatLineWidget = CreateThreatLineWidget
end

---------------
-- Tanked Widget
---------------

-- [[
do
	local Tanks = {}
	local RosterMonitor
	local artpath = "Interface\\Addons\\TidyPlates\\Widgets\\MainTanked\\"

	local function UpdateRoster()
		-- TESTING PURPOSES
		local mypet = UnitName("pet")
		if mypet then Tanks[mypet] = true; print("Adding your pet, "..mypet.." to Tanks List.") end
		-- TESTING PURPOSES
		
		local Index, raidcount
		if UnitInRaid("player") then
			for Index = 1, raidcount do
				local raidid = "raid"..tostring(Index)
				local isAssigned = GetPartyAssignment("MAINTANK", raidid)
				if isAssigned then Tanks[UnitName(raidid)] = true 
				else Tanks[UnitName(raidid)] = nil end
			end
		end
		
		-- TESTING PURPOSES
		print("Tanks:")
		for x, y in pairs(Tanks) do
			if y then print(x) end
		end
		-- TESTING PURPOSES
	end

	local function CreateRosterMonitor()
		local frame = CreateFrame("Frame")
		-- Register Events
		frame:RegisterEvent("RAID_ROSTER_UPDATE")
		frame:SetScript("OnEvent", UpdateRoster)
		UpdateRoster()
		return frame
	end

	local tankedwidgetpath = "\\"
	
	local function UpdateTankedWidget(frame, unit)
		-- "mouseovertarget" 
		local unitid, targetname
		if unit.reaction == "FRIENDLY" or (not InCombatLockdown()) then frame:Hide(); return end
		if unit.isTarget then unitid = "target"
		elseif unit.isMouseover then unitid = "mouseover" end

		if unitid then
			targetname = UnitName(unitid.."target")
			if targetname then 
				frame.FadeTime = GetTime() + 2
				frame:HideIn(frame.FadeTime)
				frame:Show()
				if Tanks[targetname] then frame.tank:Show(); frame.squishy:Hide()
				else frame.tank:Hide(); frame.squishy:Show() end
			else frame:Hide() end
		elseif (GetTime() > frame.FadeTime) then frame:Hide() end
	end

	local function CreateTankedWidget(parent)		
		-- Start Roster Monitor
		if not RosterMonitor then RosterMonitor = CreateRosterMonitor() end
		-- Init Widget
		local frame = CreateFrame("Frame", nil, parent)
		frame.FadeTime = 0
		frame:SetWidth(64)
		frame:SetHeight(64)
		-- Tank Icon
		frame.tank = frame:CreateTexture(nil, "OVERLAY")
		frame.tank:SetTexture(artpath.."Shield")
		frame.tank:SetAllPoints(frame)
		frame.tank:Hide()
		-- Squishy Icon
		frame.squishy = frame:CreateTexture(nil, "OVERLAY")
		frame.squishy:SetTexture(artpath.."Knife")
		frame.squishy:SetAllPoints(frame)
		frame.squishy:Hide()
		-- Update
		frame.HideIn = TidyPlatesWidgets.HideIn
		frame.Update = UpdateTankedWidget
		frame:Hide()
		return frame
	end
	
	TidyPlatesWidgets.CreateTankedWidget = CreateTankedWidget
end

		-- Target Name  (taken from MainTanked Widget)
		--[[
		frame.name = frame:CreateFontString(nil, "OVERLAY")
		frame.name:SetFont(threatfont, 10, "NONE")
		frame.name:SetPoint("LEFT",frame,"RIGHT", 3, 1)
		frame.name:SetWidth(50)
		frame.name:SetHeight(10)
		frame.name:SetJustifyH("LEFT")
		frame.name:SetShadowColor(0,0,0,1)
		frame.name:SetShadowOffset(1, -1)
		frame.name:SetText("Mrtanky")
		--]]

--]]
